//
//  UIImageView+WebImage.swift
//  BasicApp
//
//  Created by Wangtao0714 on 2021/3/26.
//  Copyright © 2021 Facebook. All rights reserved.
//

import Foundation
import Kingfisher
import Lottie

private var jsonAnimationViewKey: Void?

public enum WebImageError: Error {
    case emptyUrl
    case jsonInvalid
}

extension UIImageView {
    private var jsonAnimationView: AnimationView? {
        get {
            return fx_getAssociatedObject(self, &jsonAnimationViewKey)
        }
        
        set {
            if let previousJsonAnimationView = jsonAnimationView {
                previousJsonAnimationView.removeFromSuperview()
            }
            
            if let newJsonAnimationView = newValue {
                addSubview(newJsonAnimationView)
                backgroundColor = .clear
                newJsonAnimationView.contentMode = contentMode
                newJsonAnimationView.translatesAutoresizingMaskIntoConstraints = false
                newJsonAnimationView.leftAnchor.constraint(
                    equalTo: self.leftAnchor, constant: 0.0).isActive = true
                newJsonAnimationView.rightAnchor.constraint(
                    equalTo: self.rightAnchor, constant: 0.0).isActive = true
                newJsonAnimationView.topAnchor.constraint(
                    equalTo: self.topAnchor, constant: 0.0).isActive = true
                newJsonAnimationView.bottomAnchor.constraint(
                    equalTo: self.bottomAnchor, constant: 0.0).isActive = true
            }
            
            fx_setRetainedAssociatedObject(self, &jsonAnimationViewKey, newValue)
        }
    }
    
    @objc public var jsonContentMode: UIView.ContentMode {
        get {
            return contentMode
        }
        
        set {
            contentMode = newValue
            if let jsonView = jsonAnimationView {
                jsonView.contentMode = newValue
            }
        }
    }
    
    convenience init(jsonAnimationName: String, loopMode: LottieLoopMode) {
        self.init()
        jsonAnimationView = AnimationView(name: jsonAnimationName)
        jsonAnimationView?.loopMode = loopMode

    }
    
    /// 播放json动画
    @objc public func play() {
        if let jsonView = jsonAnimationView {
            jsonView.play()
        }
    }
    
    /// 停止json动画
    @objc public func stop() {
        if let jsonView = jsonAnimationView {
            jsonView.stop()
        }
    }
    
    /// 暂停json动画
    @objc public func pause() {
        if let jsonView = jsonAnimationView {
            jsonView.pause()
        }
    }
    
    /// 下载网络图片，支持json动画
    /// - Parameters:
    ///   - url: 图片url
    ///   - placeholderImage: 占位图片
    func setImage(with url: String?, placeholderImage: UIImage?) {
        setImage(with: url, placeholderImage: placeholderImage) { (img, error) in
            
        }
    }
    
    
    /// 下载网络图片
    /// - Parameters:
    ///   - URL: 图片URL
    ///   - placeholderImage: 占位图片
    func setImage(with URL: URL?, placeholderImage: UIImage?) {
        setImage(with: URL?.absoluteString ?? "", placeholderImage: placeholderImage)
    }
    
    
    /// 下载网络图片
    /// - Parameter URL: 图片URL
    func setImage(with URL: URL?) {
        setImage(with: URL, placeholderImage: nil)
    }
    
    
    /// 下载网络图片
    /// - Parameter url: 图片url
    func setImage(with url: String?) {
        setImage(with: url, placeholderImage: nil)
    }
    
    
    /// 下载网络图片
    /// - Parameters:
    ///   - url: 图片url
    ///   - placeholderImage: 占位图片
    ///   - completion: 下载完回调
    func setImage(with url: String?, placeholderImage: UIImage?, completion: @escaping (_ image:UIImage?, _ error: Error?) -> Void) {
        if let imgUrl = url {
            if imgUrl.hasSuffix(".json") {
                image = placeholderImage
                
                if let animationURL = URL(string: imgUrl) {
                    jsonAnimationView = AnimationView(url: animationURL, closure: { [weak self] error in
                        if (error != nil) {
                            
                            completion(nil, WebImageError.jsonInvalid)
                        } else {
                            self?.jsonAnimationView?.play()
                            self?.image = nil
                            completion(nil, nil)
                        }
                    })
                    jsonAnimationView?.loopMode = animationRepeatCount == 0 ? .loop : .playOnce
                } else {
                    completion(nil, WebImageError.jsonInvalid)
                }
                
            } else {
                if let jsonView = jsonAnimationView {
                    jsonView.removeFromSuperview()
                    jsonAnimationView = nil
                }
                
                kf.setImage(with: URL(string: url ?? ""),
                            placeholder: placeholderImage,
                            options: [.scaleFactor(2.0), .cacheOriginalImage, .transition(.fade(0.5)),],
                            progressBlock: nil) { (result) in
                    switch result {
                    case let .success(received):
                        completion(received.image, nil)
                    case let .failure(error):
                        completion(nil, error)
                    }
                }
            }
        } else {
            if let jsonView = jsonAnimationView {
                jsonView.removeFromSuperview()
                jsonAnimationView = nil
            }
            image = placeholderImage
            completion(nil, WebImageError.emptyUrl)
        }
    }
    
}
